home *** CD-ROM | disk | FTP | other *** search
- /* アトミックエイリアン 1994年6月8日-8月2日 */
- /* 1994年6月11日-7月20日 マシン故障 再開 7月26日
- α版完成 8月1日 β版完成 8月2日 */
-
-
- #include <stdio.h>
- #include <stdlib.h>
-
-
- #define R 32 /* 赤 */
- #define G 1024 /* 緑 */
- #define B 1 /* 青 */
-
-
- #define X 0 /* 画面左上のX座標 */
- #define Y 8 /* 画面左上のY座標 */
-
-
- char CHRFILE[]="grp.pat"; /* キャラクタパターンファイル名 */
- char SPRITE[]="spr.pat"; /* スプライトパターンファイル名 */
-
- char gwork[1536]; /* グラフイックBIOSワーク */
-
- short work[13][256]; /* 背景のキャラクタパターンワーク */
- short chr[9][64]; /* 背景のキャラクタパターン */
- short num[10][256]; /* アナログ数字のキャラクタパターン */
-
- #define WALL 6 /* 障害物のマップコードの最大値 */
-
- int MAP[30][30]; /* マップ 0:壁左上
- 1:壁右上
- 2:壁左下
- 3:壁右下
- 4:壁上辺
- 5:壁下辺
- 6:枠
- 7:dot
- 8:空白 */
-
- int end; /* ゲーム終了フラグ 0:続行 1:ゲーム終了 */
- int game_over; /* ゲームオーバーフラグ 0:続行 1:ゲームオーバー */
-
- int hi_score,score;
-
- #define SPK 6 /* 人のスピード */
- int spk; /* 人のスピードワーク */
- int kx,ky; /* 人の座標 */
- int kh; /* 人の向き 0:上 1:下 2:左 3:右 */
- int life; /* 人の残り */
- int gain; /* 人追加フラグ 0:未追加 1:追加済 */
- int dot; /* ドットの残り数 */
-
- #define SPB 1 /* 矢のスピード */
- int spb; /* 矢のスピードワーク */
- int bx,by; /* 矢の座標 */
- int bh; /* 矢の向き 0:上 1:下 2:左 3:右 */
- int bj; /* 矢の状態 0:発射可能 1:飛行中 2:発射準備 */
-
- #define LIMIT 3100 /* ボスエイリアンが仮死状態でいる時間(定数) */
- int limit; /* ボスエイリアンが蘇るまでのリミットタイム */
- int max_alien; /* エイリアンの最大数 */
- int left_alien; /* エイリアンの残り数 */
- int clear; /* ステージクリアフラグ */
-
- #define SPA00 7 /* ボスエイリアンのスピード(平常時) */
- #define SPA01 6 /* ボスエイリアンのスピード(残り1匹時) */
- #define SPA10 9 /* ザコエイリアンのスピード(ドット残りあり) */
- #define SPA11 7 /* ザコエイリアンのスピード(ドット残りなし) */
- int SPA[8]; /* エイリアンのスピード */
- int spa[8]; /* エイリアンのスピードワーク */
- int ax[8],ay[8]; /* エイリアンの座標 */
- int ah[8]; /* エイリアンの向き 0:上 1:下 2:左 3:右 */
- int aj[8]; /* エイリアンの状態 0:死亡 1:生存 */
- int aj[8]; /* エイリアンの状態 0:死亡 1:生存 */
- int dumm_boss; /* ボスエイリアンのダメージ */
-
- /* サウンド変数 */
- int spoint[6]; /* サウンドデータポインタ */
- int sinit[28]; /* サウンドデータ先頭ポインタ */
- int skunt[6]; /* カウンタ */
- int feed[6]={1,1,7,1,1,1}; /* 各チャンネルの音質 */
- /* チャンネル 0 : エイリアンワープ音,人死亡音,
- ボス仮死音,ボスダメージ音,ボス死亡音,ザコ死亡音
- 1 : ドット喰い音,リミット減少音
- 2 : アロー発射音
- 3 : 仮死ボス命中音
- 4 : 人追加音
- 5 : ボス目覚め音
- */
-
- #define T0 7 /* ドット喰い音のテンポ */
- #define T1 70 /* エイリアンワープ音のテンポ */
- #define T2 70 /* 人死亡音のテンポ */
- #define T3 70 /* ボス仮死音のテンポ */
- #define T4 70 /* ボスダメージ音のテンポ */
- #define T5 70 /* ボス死亡音のテンポ */
- #define T6 70 /* ザコ死亡音のテンポ */
- #define T7 7 /* アロー発射音のテンポ */
- #define T8 50 /* 仮死ボス命中音のテンポ */
- #define T9 70 /* 人追加音のテンポ */
- #define T10 27 /* ボス目覚め音のテンポ */
- #define T11 10 /* リミット減少音のテンポ */
-
- int sdata[]={ /* サウンドデータ OCT,TONE,VOL,LONG */
- /* 音階 0 1 2 3 4 5 6 7 8 9 10 11 12
- 休 C C# D D# E F F# G G# A A# B */
- -1, /* No0 ドット喰い音 */
- 5, 1,13,T0,
- 5, 1,15,T0,
- 5, 1,17,T0,
- 1, 0,128,0,
-
- -1, /* No1 エイリアンワープ音 */
- 5,1 ,11,T1,
- 5,2 ,13,T1,
- 5,1 ,15,T1,
- 5,2 ,17,T1,
- 5,1 ,19,T1,
- 5,2 ,21,T1,
- 5,1 ,23,T1,
- 5,2 ,25,T1,
- 1, 0,128,0,
-
- -1, /* No2 人死亡音 */
- 5,10,11,T2,
- 5, 6,11,T2,
- 5, 3,11,T2,
- 5,10,11,T2,
- 5, 6,11,T2,
- 5, 3,11,T2,
- 5,10,11,T2,
- 5, 6,11,T2,
- 5, 3,11,T2,
- 5,10,11,T2,
- 5, 6,11,T2,
- 5, 3,11,T2,
- 5,10,11,T2,
- 5, 6,11,T2,
- 5, 3,11,T2,
- 5,10,11,T2,
- 5, 6,11,T2,
- 5, 3,11,T2,
- 1, 0,128,0,
-
- -1, /* No3 ボス仮死音 */
- 5, 8,11,T3,
- 5, 1,11,T3,
- 5,10,11,T3,
- 5, 2,11,T3,
- 5, 8,11,T3,
- 5, 1,11,T3,
- 5,10,11,T3,
- 5, 2,11,T3,
- 5, 8,11,T3,
- 5, 1,11,T3,
- 5,10,11,T3,
- 5, 2,11,T3,
- 5, 8,11,T3,
- 5, 1,11,T3,
- 5,10,11,T3,
- 5, 2,11,T3,
- 1, 0,128,0,
-
- -1, /* No4 ボスダメージ音 */
- 4,12,11,T4,
- 5, 3,11,T4,
- 5, 8,11,T4,
- 4,12,11,T4,
- 5, 3,11,T4,
- 5, 8,11,T4,
- 4,12,11,T4,
- 5, 3,11,T4,
- 5, 8,11,T4,
- 4,12,11,T4,
- 5, 3,11,T4,
- 5, 8,11,T4,
- 1, 0,128,0,
-
- -1, /* No5 ボス死亡音 */
- 5, 5,11,T5,
- 5, 3,11,T5,
- 5, 8,11,T5,
- 5, 6,11,T5,
- 5, 5,11,T5,
- 5, 3,11,T5,
- 5, 8,11,T5,
- 5, 6,11,T5,
- 5, 5,11,T5,
- 5, 3,11,T5,
- 5, 8,11,T5,
- 5, 6,11,T5,
- 1, 0,128,0,
-
- -1, /* No6 ザコ死亡音 */
- 5, 3,11,T6,
- 5, 6,11,T6,
- 5, 8,11,T6,
- 5, 6,11,T6,
- 5, 3,11,T6,
- 5, 6,11,T6,
- 5, 8,11,T6,
- 5, 6,11,T6,
- 5, 3,11,T6,
- 5, 6,11,T6,
- 5, 8,11,T6,
- 5, 6,11,T6,
- 5, 3,11,T6,
- 5, 6,11,T6,
- 5, 8,11,T6,
- 5, 6,11,T6,
- 1, 0,128,0,
-
- -1, /* No7 アロー発射音 */
- 6,12,15,T7,
- 6,11,15,T7,
- 6,10,15,T7,
- 6, 9,15,T7,
- 6, 8,15,T7,
- 6, 7,15,T7,
- 6, 6,15,T7,
- 6, 5,15,T7,
- 6, 4,15,T7,
- 6, 3,15,T7,
- 6, 2,15,T7,
- 6, 1,15,T7,
- 1, 0,128,0,
-
- -1, /* No8 仮死ボス命中音 */
- 7, 8,17,T8,
- 7, 1,17,T8,
- 7,10,17,T8,
- 7,12,17,T8,
- 1, 0,128,0,
-
- -1, /* No9 人追加音 */
- 5, 1,11,T9,
- 5, 5,11,T9,
- 5, 8,11,T9,
- 5, 1,11,T9,
- 5, 5,11,T9,
- 5, 8,11,T9,
- 5, 1,11,T9,
- 5, 5,11,T9,
- 5, 8,11,T9,
- 1, 0,128,0,
-
- -1, /* No10 ボス目覚め音 */
- 3, 1,11,T10,
- 3, 2,11,T10,
- 3, 3,11,T10,
- 3, 4,11,T10,
- 3, 5,11,T10,
- 3, 6,11,T10,
- 3, 7,11,T10,
- 3, 8,11,T10,
- 3, 9,11,T10,
- 3,10,11,T10,
- 3,11,11,T10,
- 3,12,11,T10,
- 4, 1,11,T10,
- 4, 2,11,T10,
- 4, 3,11,T10,
- 4, 4,11,T10,
- 4, 5,11,T10,
- 4, 6,11,T10,
- 4, 7,11,T10,
- 4, 8,11,T10,
- 4, 9,11,T10,
- 4,10,11,T10,
- 4,11,11,T10,
- 4,12,11,T10,
- 5, 1,11,T10,
- 5, 2,11,T10,
- 5, 3,11,T10,
- 5, 4,11,T10,
- 5, 5,11,T10,
- 5, 6,11,T10,
- 5, 7,11,T10,
- 5, 8,11,T10,
- 5, 9,11,T10,
- 5,10,11,T10,
- 5,11,11,T10,
- 5,12,11,T10,
- 1, 0,128,0,
-
- -1, /* No11 リミット減少音 */
- 5,10,11,T11,
- 5,10,12,T11,
- 5,10,13,T11,
- 5,10,14,T11,
- 5,10,15,T11,
- 5,10,16,T11,
- 5,10,17,T11,
- 5,10,18,T11,
- 5,10,19,T11,
- 5,10,20,T11,
- 5,10,22,T11,
- 5,10,24,T11,
- 5,10,26,T11,
- 5,10,28,T11,
- 5,10,30,T11,
- 5,10,34,T11,
- 5,10,38,T11,
- 1, 0,128,0,
-
- -1,
- -2
- };
-
-
-
- main()
- {
- int i,j;
- int dx,dy;
-
- end=0; /* ゲーム終了フラグ */
-
- if (load_chr()==0) return 0; /* キャラクタパターンデータのバイナリ形式load */
- make_chr(); /* キャラクタパターンデータの8×8分割 */
- for (i=0;i<64;i++) chr[8][i]=1; /* 空白パターン作成 */
- hi_score=0;
-
- g_init(gwork); /* グラフィック画面の初期化 */
- sprite(1); /* スプライト表示開始 */
- SPR_display(1,120); /* スプライトの表示個数 */
-
- binit(); /* サウンド処理初期化 */
-
- if (load_sprite()==0) return 0; /* スプライトパターンのバイナリ形式read */
-
- while(1) /* メインループ */
- {
- demo(); /* デモ */
- if (end==1) break; /* ゲーム終了 */
- title(0); /* タイトル表示 */
-
- game_over=0;
- life=5; /* 人の残り */
- gain=0; /* 人追加フラグ */
- max_alien=2;
- score=0;
- while(game_over==0) /* 1ゲームループ */
- {
- dot=389; /* ドットの残り */
- map(0); /* フィールドの作成 */
- init(0); /* 1面初期化 */
- while( (clear==0) && (game_over==0) ) /* 1面ループ */
- {
- alien(); /* エイリアンの移動 */
- spk++; if (spk>SPK) {move(); timer(); spk=0;}; /* 人の移動 */
- spb++; if (spb>SPB) {arrow(); spb=0;}; /* 矢の移動 */
- if ((INPB(0x04d0) & 0x03)==0) game_over=1; /* SELECTボタン -> 強制終了 */
- if ((INPB(0x04d0) & 0x0c)==0) /* RUNボタン -> PAUSE */
- {
- fm_init(); /* 音の停止 */
- while((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
- dx=108; dy=240;
- EGB_color(gwork,0,R*31); EGB_putSjis(gwork,dx,dy,"PAUSE");
- while((INPB(0x04d0) & 0x0c)!=0); /* RUNボタンを押すまで待つ */
- for (j=0;j<16;j++) {for (i=0;i<40;i++) g_pset(g_loc(dx+i,dy-j),0);};
- EGB_color(gwork,0,0x7fff);
- while((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
- };
- bgm(); /* サウンド処理 */
- wait();
- for (i=0;i<max_alien;i++) /* エイリアンと人の接触判定 */
- {if ((aj[i]>0)&&(abs(ax[i]-kx)<6)&&(abs(ay[i]-ky)<6)) dead();};
- if ( (gain==0) && (score>=800) ) /* 人を追加 */
- {gain=1; life++; pr_life();
- spoint[4]=sinit[9]; skunt[4]=0;}; /* 人追加音 */
- };
- fm_init(); for (i=0;i<6;i++) spoint[i]=0; /* 音の停止 */
- for (i=0;i<1000;i++) wait();/* 面クリア後の余韻 */
- max_alien++; if (max_alien>=8) max_alien=3;
- };
- /* ゲームオーバー処理 */
- for (i=0;i<60;i++) sp_dsp(i,0);
- dx=X+52; dy=Y+104;
- EGB_color(gwork,0,1); EGB_putSjis(gwork,dx+2,dy+2,"GAME OVER");
- EGB_color(gwork,0,(R+G)*31);EGB_putSjis(gwork,dx+1,dy+1,"GAME OVER");
- EGB_color(gwork,0,R*31); EGB_putSjis(gwork,dx,dy,"GAME OVER");
- if (score>hi_score) /* ハイスコア取得 */
- {
- hi_score=score; pr_score(1);
- EGB_color(gwork,0,1);
- EGB_putSjis(gwork,dx+4+1,dy+48+1,"You Get Hi-SCORE.");
- EGB_color(gwork,0,(R+G)*31);
- EGB_putSjis(gwork,dx+4,dy+48,"You Get Hi-SCORE.");
- };
- EGB_color(gwork,0,1); EGB_putSjis(gwork,dx+12+1,dy+100+1,"Push A button");
- EGB_color(gwork,0,R*31); EGB_putSjis(gwork,dx+12,dy+100,"Push A button");
- while ((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
- while ((INPB(0x04d0) & 0x10)==0x10); /* Aボタンを押すまで待つ */
- };
-
- while ((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
-
-
- fm_init(); /* FM音源の停止 */
- g_cls();
- sprite(0); /* スプライト表示停止 */
-
- screenterm( gwork ) ; /* MS-DOSの画面モード */
-
- };
-
-
-
- title(mode)
- /* タイトル表示 */
- int mode; /* 0:本番用 1:デモ用 */
- {
- int dx,dy;
-
- EGB_fontStyle(gwork,1); /* 太文字 */
- EGB_textZoom(gwork,0,8,16); /* ANKの拡大率 */
- dx=252; dy=24;
- EGB_color(gwork,0,R*31); EGB_putSjis(gwork,dx+2,dy+2,"Atomic");
- EGB_color(gwork,0,(R+G)*31); EGB_putSjis(gwork,dx+1,dy+1,"Atomic");
- EGB_color(gwork,0,0x7fff); EGB_putSjis(gwork,dx,dy,"Atomic");
- dy=dy+16;
- EGB_color(gwork,0,R*31); EGB_putSjis(gwork,dx+2,dy+2," ALIEN");
- EGB_color(gwork,0,(R+G)*31); EGB_putSjis(gwork,dx+1,dy+1," ALIEN");
- EGB_color(gwork,0,0x7fff); EGB_putSjis(gwork,dx,dy," ALIEN");
- EGB_color(gwork,0,0x7fff);
- dy=dy+32; EGB_putSjis(gwork,dx,dy,"Hi-SCORE");
- if (mode!=1)
- { /* 本番用インフォーメーション */
- dy=dy+40; EGB_putSjis(gwork,dx,dy,"SCORE");
- dy=dy+40; EGB_putSjis(gwork,dx,dy,"Life");
- dy=dy+40; EGB_putSjis(gwork,dx,dy,"Limit");
- dy=dy+20; EGB_putSjis(gwork,dx,dy," Boss");
- }
- else
- { /* デモ用インフォーメーション */
- EGB_color(gwork,0,(R+G)*31);
- dy=dy+48; EGB_putSjis(gwork,dx,dy, "Abutton");
- EGB_putSjis(gwork,dx,dy+18,"→ START");
- EGB_color(gwork,0,(B+G)*31);
- dy=dy+40; EGB_putSjis(gwork,dx,dy, "Bbutton");
- EGB_putSjis(gwork,dx,dy+18,"→ About");
- EGB_color(gwork,0,R*31);
- dy=dy+40; EGB_putSjis(gwork,dx,dy, "SELECT");
- EGB_putSjis(gwork,dx,dy+18,"→ Exit");
- EGB_color(gwork,0,0x7fff);
- };
-
- };
-
-
- demo()
- /* デモ */
- {
- int i;
-
- g_cls();
- while ((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
-
- title(1); /* タイトル表示 */
- life=score=0; max_alien=8; dot=389;
- map(1); /* フィールドの作成(デモ用) */
- init(1); /* 1面初期化(デモ用) */
-
- while (1) /* デモループ */
- {
- alien(); /* エイリアンの移動 */
- wait();
- i=INPB(0x04d0);
- if ( (i & 0x10)==0 ) break; /* Aボタン */
- if ( (i & 0x20)==0 ) teach(); /* Bボタン */
- if ( (i & 0x03)==0 ) {end=1; break;}; /* SELECTボタン */
- };
- for (i=0;i<60;i++) sp_dsp(i,0);
- g_cls();
-
- };
-
-
- short pat[8][8]; /* スプライトから作成したグラフィックパターン格納領域 */
-
- teach()
- /* 説明表示 */
- {
- int i,x,y;
-
- while ((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
- for (i=0;i<60;i++) sp_dsp(i,0);
- g_cls();
-
- EGB_color(gwork,0,0x7fff);
- x=16; y=24; EGB_putSjis(gwork,160-16,y,"説明");
-
- y=y+20; sp_gr(0,0); g_put8(g_loc(x,y-12),pat);
- EGB_putSjis(gwork,x+10,y,"を操作して、フィールド内のエイリアン");
- EGB_putSjis(gwork,x,y+16,"を全て抹殺せよ");
-
- y=y+40; g_put8(g_loc(x,y-12),chr[7]);
- EGB_putSjis(gwork,x+10,y,"が残っている間は、エイリアンを撃っても");
- EGB_putSjis(gwork,x,y+16,"死なずにワープする");
-
- y=y+40; g_put8(g_loc(x,y-12),chr[7]);
- EGB_putSjis(gwork,x+10,y,"がなくなってから、 を撃つと、しばらく");
- sp_gr(12,0); g_put8(g_loc(x+16*8+12+10,y-12),pat);
- EGB_putSjis(gwork,x,y+16,"の間は仮死状態( )になる");
- sp_gr(14,0); g_put8(g_loc(x+16*7+12,y+16-12),pat);
-
- y=y+40; EGB_putSjis(gwork,x,y,"その間に を撃つと死亡する");
- sp_gr(10,0); g_put8(g_loc(x+16*4+4,y-12),pat);
-
- y=y+22; sp_gr(10,0); g_put8(g_loc(x,y-12),pat);
- EGB_putSjis(gwork,x+10,y,"が全滅してから、 に3発命中させれば");
- sp_gr(12,0); g_put8(g_loc(x+16*7+12+10,y-12),pat);
- EGB_putSjis(gwork,x,y+16,"ラウンドクリア");
-
- EGB_putSjis(gwork,88,232,"Push A button");
-
-
- while ((INPB(0x04d0) & 0x10)==0x10); /* Aボタンを押すまで待つ */
- g_cls();
- while ((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
-
- /* 画面を元に戻す */
- title(1); /* タイトル表示 */
- map(1); /* フィールドの作成(デモ用) */
- init(1); /* 1面初期化(デモ用) */
-
- };
-
-
- dead()
- /* 人の死亡 */
- {
- int i,j,k,add,f;
-
- /* 死亡デモ */
- spoint[0]=sinit[2]; skunt[0]=0; /* 人死亡音 */
- for (j=0;(sdata[spoint[0]]!=-1);j++)
- {sp_pat(0,15+((j>>4) & 1)); bgm(); wait();};
- for (i=0;i<60;i++) sp_dsp(i,0); /* スプライト消去 */
- fm_init(); for (i=0;i<6;i++) spoint[i]=0; /* 音の停止 */
- life--; if (life==0) {game_over=1; pr_life(); return 0;};
-
- for (i=0;i<500;i++) wait(); /* ウェイト */
- init(0);
- if (dot==0) /* ドットがない状態ならドットを1つ配置する */
- {
- while(1) {i=rnd(26)+2; j=rnd(22)+2;
- for (k=f=0;k<8;k++) /* エイリアンに重なるか */
- {if ( (aj[k]==1) && ((ax[k]/8)==i) && ((ay[k]/8)==j) ) f=1;};
- if (f==1) continue; /* 重なった */
- if (MAP[j][i]==8) {MAP[j][i]=7; break;};};
- dot=1; add=g_loc(i*8+X,j*8+Y);
- spoint[5]=sinit[10]; skunt[5]=0; /* ボス目覚め音(代用) */
- for (k=0;(sdata[spoint[5]]!=-1);k++) /* ドット配置デモ */
- {if ( (k%16)<7 ) g_put8(add,chr[7]); else g_put8(add,chr[8]);
- bgm(); wait(); wait();};
- g_put8(add,chr[7]); /* ドットの表示 */
- for (i=0;i<700;i++) wait(); /* ウェイト */
- };
-
- };
-
-
- init(mode)
- /* 変数の初期化 */
- int mode; /* 0:本番用(ワープ音あり) 1:デモ用(ワープ音なし) */
- {
- int i,j,f;
-
-
- pr_score(1); /* ハイスコア表示 */
-
- if (mode!=1) /* 本番時のみインフォーメーション表示 */
- {
- pr_score(0); /* スコア表示 */
- pr_life(); /* 残り人数表示 */
- left_alien=max_alien; /* エイリアンの数 */
- limit=dumm_boss=0; /* ボスエイリアンのダメージ */
- information(); /* 制限時間の表示 */
- clear=0; /* ステージクリアフラグ */
- };
-
- spk=0; /* 人のスピードワーク */
- kx=(31-2)*8+X+1; ky=(27-3)*8+Y; kh=2; /* 人変数の初期化 */
- if (mode!=1) /* デモでなければ人を表示 */
- {sp_init(0,kx+X,ky+Y,0,kh,0); sp_dsp(0,1);}; /* 人のスプライトの初期化 */
-
- bj=0; /* 矢の状態 0:発射可能 1:飛行中 2:発射準備 */
- spb=0; /* 矢のスピードワーク */
- sp_init(1,bx,by,0,0,0); sp_dsp(1,0); /* 矢のスプライトの初期化 */
-
- for (i=0;i<8;i++) {aj[i]=spa[i]=0; SPA[i]=SPA00;}; /* エイリアンの初期設定 */
- for (i=0;i<max_alien;i++)
- {
- if (i==0) {SPA[0]=SPA00; j=12;} /* ボスのスピード初期値とキャラクタNo */
- else {SPA[i]=SPA10; j=8;}; /* ザコのスピード初期値とキャラクタNo */
- aj[i]=1; spa[i]=i; warp(i); /* 座標等 */
- sp_init(i+2,ax[i]+X,ay[i]+Y,0,j,0);
- sp_dsp(i+2,1); /* alienのスプライトの初期化 */
- if (mode!=1) {spoint[0]=sinit[1]; skunt[0]=0; warp(-1);}; /* ワープ音 */
- };
- if (mode!=1) {for (i=0;i<700;i++) wait();}; /* ウェイト */
-
- };
-
-
- map(mode)
- /* フィールドの作成 */
- int mode; /* 0:本番用マップ作成 1:デモ用マップ作成 */
- {
- int i,j;
- int mx=31,my=27;
-
- if (mode==1) /* デモならテロップ表示 */
- {EGB_color(gwork,0,R*31); EGB_putSjis(gwork,96,240,"DEMO");};
-
- /* 本番ならdotで、デモなら空白で通路をうめる */
- for (j=0;j<my;j++) {for (i=0;i<mx;i++) MAP[j][i]=7+mode;};
-
- for (j=0;j<my;j++) MAP[j][0]=MAP[j][mx-1]=6; /* 縦枠 */
- for (i=0;i<mx;i++) MAP[0][i]=MAP[my-1][i]=6; /* 横枠 */
-
- for (j=2;j<(my-3);j=j+3) /* コーナー */
- {
- for (i=2;i<(mx-4);i=i+4)
- {
- MAP[j][i]=0; MAP[j][i+1]=4; MAP[j][i+2]=1;
- MAP[j+1][i]=2; MAP[j+1][i+1]=5; MAP[j+1][i+2]=3;
- };
- };
-
- for (j=0;j<my;j++) /* マップ表示 */
- {for (i=0;i<mx;i++) g_put8(g_loc(i*8+X,j*8+Y),chr[MAP[j][i]]);};
-
- };
-
-
- move()
- /* 人の移動 */
- {
- int p,i;
-
- p=INPB(0x04d0);
-
- /* 現在と反対方向へは随時方向転換可能 */
- if ( ((p & 0x01)==0) && (kh==1) ) kh=0; /* 上 */
- if ( ((p & 0x02)==0) && (kh==0) ) kh=1; /* 下 */
- if ( ((p & 0x04)==0) && (kh==3) ) kh=2; /* 左 */
- if ( ((p & 0x08)==0) && (kh==2) ) kh=3; /* 右 */
-
- /* それ以外の方向は8×8の枠内なら方向転換可能 */
- if ( ((kx%8)==0) && ((ky%8)==0) )
- { /* 変更後の方向に進めれば方向を変更 */
- if ( ((p & 0x01)==0) && (MAP[(ky-1)/8][kx/8]>WALL) ) kh=0; /* 上 */
- if ( ((p & 0x02)==0) && (MAP[(ky+8)/8][kx/8]>WALL) ) kh=1; /* 下 */
- if ( ((p & 0x04)==0) && (MAP[ky/8][(kx-1)/8]>WALL) ) kh=2; /* 左 */
- if ( ((p & 0x08)==0) && (MAP[ky/8][(kx+8)/8]>WALL) ) kh=3; /* 右 */
- };
-
- switch(kh)
- { /* 進んだ先が障害物でなければ移動 */
- case 0: if (MAP[(ky-1)/8][kx/8]>WALL) ky--; break; /* 上 */
- case 1: if (MAP[(ky+8)/8][kx/8]>WALL) ky++; break; /* 下 */
- case 2: if (MAP[ky/8][(kx-1)/8]>WALL) kx--; break; /* 左 */
- case 3: if (MAP[ky/8][(kx+8)/8]>WALL) kx++; break; /* 右 */
- };
-
- /* dot処理 */
- if ( (MAP[ky/8][kx/8]==7) && ((kx%8)==0) && ((ky%8)==0) )
- {
- MAP[ky/8][kx/8]=8; g_put8(g_loc(kx/8*8+X,ky/8*8+Y),chr[8]);
- dot--; /* ドットの残り */
- score++; pr_score(0); /* スコア表示 */
- spoint[1]=sinit[0]; skunt[1]=0; /* ドット喰い音 */
- if (dot==0) {for (i=1;i<8;i++) SPA[i]=SPA11;}; /* ドット0=>ザコのスピードアップ */
- };
-
- sp_pat(0,kh); sp_move(0,kx+X,ky+Y); /* 人の表示 */
-
-
- if ((p & 0x10)==0) /* Aボタン */
- {if (bj==0) {bj=1; bh=kh; bx=kx; by=ky; /* 矢を発射 */
- spoint[2]=sinit[7]; skunt[2]=0; /* アロー発射音 */
- sp_init(1,bx+X,by+Y,0,bh+4,0); sp_dsp(1,1);};}
- else {if (bj==2) bj=0;}; /* 矢の発射準備 */
-
- };
-
-
- arrow()
- /* 矢の移動 */
- {
- int f=0; /* 消滅フラグ 0:飛行続行 1:飛行中断 */
- int i;
-
- if (bj!=1) return 0; /* 矢が飛行していない */
-
- switch(bh)
- { /* 移動(進んだ先が障害物なら飛行中断) */
- case 0: if (MAP[(by-1)/8][bx/8]>WALL) by--; else f=1; /* 上 */
- break;
- case 1: if (MAP[(by+8)/8][bx/8]>WALL) by++; else f=1; /* 下 */
- break;
- case 2: if (MAP[by/8][(bx-1)/8]>WALL) bx--; else f=1; /* 左 */
- break;
- case 3: if (MAP[by/8][(bx+8)/8]>WALL) bx++; else f=1; /* 右 */
- break;
- };
-
- for (i=0;i<8;i++) /* エイリアンとの命中判定 */
- {
- if ( (abs(bx-ax[i])<7) && (abs(by-ay[i])<7) && (aj[i]!=0) )
- {
- f=1; sp_dsp(1,0); /* 矢を消す */
- if (dot==0) /* ドットが無い */
- {
- if (i==0) /* ボス */
- {
- if (aj[0]==2) /* ボスが仮死状態なら矢は消滅 */
- {spoint[3]=sinit[8]; skunt[3]=0; break;}; /* 仮死ボス命中音 */
- if (left_alien==1) /* 全てのザコが死亡 */
- {
- dumm_boss++; /* ボスエイリアンのダメージ増加 */
- score=score+10;
- information(); /* 制限時間とダメージの表示 */
- if (dumm_boss>=3)
- {
- aj[i]=0; sp_dsp(i+2,0); /* 死亡 */
- score=score+20; clear=1; /* 面クリア */
- spoint[0]=sinit[5]; skunt[0]=0; /* ボス死亡音 */
- }
- else {spoint[0]=sinit[4]; skunt[0]=0;}; /* ボスダメージ音 */
- warp(0); /* ワープ */
- break;
- }
- else /* ザコが残っている */
- {
- sp_pat(2,14); aj[0]=2; limit=LIMIT; score=score+7; /* 仮死状態 */
- spoint[0]=sinit[3]; skunt[0]=0; warp(-1); /* ボス仮死音 */
- break;
- };
- }
- else /* ザコ */
- {
- if (aj[0]==2) /* ボスが仮死状態 */
- {aj[i]=0; sp_dsp(i+2,0); score=score+10; left_alien--; /* 死亡 */
- spoint[0]=sinit[6]; skunt[0]=0; warp(-1);} /* ザコ死亡音 */
- else {score=score+5; /* ボスが健在ならワープ */
- spoint[0]=sinit[1]; skunt[0]=0; warp(i);}; /* ワープ音 */
- break;
- };
- }
- else /* ドットが残っている */
- {
- spoint[0]=sinit[1]; skunt[0]=0; /* ワープ音 */
- warp(i); /* ボスもザコもワープ */
- score=score+5;
- break;
- };
- };
- };
-
- if (f==1) {sp_dsp(1,0); bj=2; pr_score(0); /* スコア表示 */}; /* 飛行中断 */
-
- sp_move(1,bx+X,by+Y); /* 矢の表示 */
-
- };
-
-
- warp(no)
- /* エイリアンのワープ */
- int no; /* エイリアンの番号 */
- {
- int f; /* ワープ先座標採用フラグ 0:採用 1:不採用 */
- int i,x,y;
-
- if (no==-1) goto sound; /* 音出しのみ */
-
- x=(ax[no]/8)*8; y=(ay[no]/8)*8; /* ワープ前の位置保存 */
- while(1)
- {
- f=0; ax[no]=(rnd(28)+1)*8; ay[no]=(rnd(24)+1)*8;
- if ( (abs(ax[no]-x)<16) && (abs(ay[no]-y)<16) ) f=1; /* 元の位置に重なる */
- if ( (abs(ax[no]-kx)<16) && (abs(ay[no]-ky)<16) ) f=1; /* 人に重なる */
- for (i=0;i<8;i++) /* 他のエイリアンに重なる */
- {if ( (no!=i) && (aj[i]==1)
- && (abs(ax[no]-ax[i])<8) && (abs(ay[no]-ay[i])<8) ) f=1;};
- if (MAP[ay[no]/8][ax[no]/8]<=WALL) f=1; /* 障害物に重なる */
- if (f==0) break; /* 座標が採用された */
- };
-
- while(1) /* 乱数による方向決定 */
- {
- ah[no]=rnd(3);
- if ( (ah[no]==0) && (MAP[(ay[no]-1)/8][ax[no]/8]>WALL) ) break; /* 上*/
- if ( (ah[no]==1) && (MAP[(ay[no]+8)/8][ax[no]/8]>WALL) ) break; /* 下*/
- if ( (ah[no]==2) && (MAP[ay[no]/8][(ax[no]-1)/8]>WALL) ) break; /* 左*/
- if ( (ah[no]==3) && (MAP[ay[no]/8][(ax[no]+8)/8]>WALL) ) break; /* 右*/
- };
-
- sp_move(no+2,ax[no]+X,ay[no]+Y); /* エイリアンの表示 */
-
- sound: /* 音出し兼ウェイト */
- while(sdata[spoint[0]]!=-1) {bgm(); for (i=0;i<2;i++) wait();};
-
- };
-
-
- timer()
- /* ボスエイリアンの目覚め時間 */
- {
- int i;
- int wlimit;
-
- if (limit==0) return 0;
-
- wlimit=limit/100; limit--;
- if (wlimit!=limit/100) {information(); /* 制限時間の表示 */
- spoint[1]=sinit[11]; skunt[1]=0;}; /* リミット減少音*/
-
- if (left_alien==1) /* ザコ全滅ならボスを即復活 & スピードアップ */
- {limit=0; information(); SPA[0]=SPA01;};
-
- if (limit<=0)
- {
- aj[0]=1; dumm_boss=0; /* ボスエイリアンのダメージ復活 */
- spoint[5]=sinit[10]; skunt[5]=0; /* ボス目覚め音 */
- for (i=0;(sdata[spoint[5]]!=-1);i++) /* 目覚めデモ */
- {if ( (i%16)<7 ) sp_pat(2,12); else sp_pat(2,14);
- bgm(); wait(); wait();};
- };
-
-
- };
-
-
- information()
- /* 制限時間の表示 */
- {
- int x,y;
- int add;
- int wlimit;
-
- /* 制限時間の表示 */
- x=296; y=176; add=g_loc(x,y);
- wlimit=limit;
- g_put(add,num[wlimit/1000]); wlimit=wlimit%1000;
- g_put(add+20,num[wlimit/100]);
-
- /* ボスのダメージの表示 */
- x=x+8; y=y+20; add=g_loc(x,y); g_put(add,num[3-dumm_boss]);
-
- };
-
-
- pr_score(mode)
- /* スコアの表示 */
- int mode; /* 0:スコア表示 1:ハイスコア表示 */
- {
- int x,y;
- int add;
- int wscore;
-
- switch(mode)
- {
- case 0 : x=256; y=112; wscore=score; break;
- case 1 : x=256; y=72; wscore=hi_score; break;
- };
- add=g_loc(x,y+1);
-
- g_put(add,num[wscore/10000]); wscore=wscore%10000;
- g_put(add+20,num[wscore/1000]); wscore=wscore%1000;
- g_put(add+40,num[wscore/100]); wscore=wscore%100;
- g_put(add+60,num[wscore/10]);
- g_put(add+80,num[wscore%10]);
- g_put(add+100,num[0]);
-
- };
-
-
- pr_life()
- /* 残り人数表示 */
- {
- int i;
- int x,y,add;
- short blank[64];
-
- x=256; y=136; g_put(g_loc(x+36,y),num[life]);
-
- sp_gr(0,0); /* 残り表示用グラフィックパターンの作成 */
- for (i=0;i<64;i++) blank[i]=0;
-
- add=g_loc(x,y+16+1);
- for (i=0;i<5;i++) g_put8(add+18*i,blank); /* 残り表示領域の消去 */
- if (life<1) return 0; /* 残り表示は数値のみで良い */
- for (i=0;i<5;i++) if ((life-1)>i) g_put8(add+18*(4-i),pat); /* 残り表示 */
-
- };
-
-
- sp_gr(no,pal)
- /* スプライトパターンからグラフィックパターン(8×8)を作成 */
- int no; /* スプライトパターン番号 */
- int pal; /* カラーパレット番号 */
- {
- int x,y;
-
- for (y=0;y<8;y++)
- {
- for (x=0;x<8;x++) pat[y][x]=sp_point(no,x,y,pal);
- };
-
- };
-
-
- alien()
- /* エイリアンの移動 */
- {
- int no;
- int i;
- int wah;
- int s; /* 方向転換フラグ(ワーク) 0:方向転換可能 1:方向転換不可 */
-
- for (no=0;no<8;no++)
- {
- spa[no]++; if (spa[no]<SPA[no]) continue; spa[no]=0; /* タイマー */
- if (aj[no]==0) {for (i=0;i<100;i++); continue;}; /* 死亡エイリアンをとばす*/
-
- wah=(ah[no]&2)+((ah[no]+1)&1); /* 現在の方向の反対方向 */
- if ( ((ax[no]%(4*8))==(8*1)) && ((ay[no]%(3*8))==(8*1)) ) /* 交差点 */
- {
- s=0;
- if (rnd(1)==0) /* 現在の方向に進めれば1/2の確率で方向を維持 */
- {
- if ( (ah[no]==0) && (MAP[(ay[no]-1)/8][ax[no]/8]>WALL) ) s=1; /* 上 */
- if ( (ah[no]==1) && (MAP[(ay[no]+8)/8][ax[no]/8]>WALL) ) s=1; /* 下 */
- if ( (ah[no]==2) && (MAP[ay[no]/8][(ax[no]-1)/8]>WALL) ) s=1; /* 左 */
- if ( (ah[no]==3) && (MAP[ay[no]/8][(ax[no]+8)/8]>WALL) ) s=1; /* 右 */
- }
- if (rnd(9)==1) /* 1/10確率で追跡するかを決定 */
- { /* 追跡 */
- while(s==0)
- {
- if ( (abs(ax[no]-kx)<8) && (abs(ay[no]-ky)<8) )
- {ah[no]=(ah[no]&2)+((ah[no]+1)&1); break;};/*無限ループ防止(テスト用)*/
- if (rnd(1)==0) /* 1/2の確率でX,Y方向の優先度を決定 */
- {
- if (ay[no]>ky) ah[no]=0;
- if (ay[no]<ky) ah[no]=1;
- }
- else
- {
- if (ax[no]>kx) ah[no]=2;
- if (ax[no]<kx) ah[no]=3;
- };
- if ( (ah[no]==0) && (MAP[(ay[no]-1)/8][ax[no]/8]>WALL) ) s=1;/* 上 */
- if ( (ah[no]==1) && (MAP[(ay[no]+8)/8][ax[no]/8]>WALL) ) s=1;/* 下 */
- if ( (ah[no]==2) && (MAP[ay[no]/8][(ax[no]-1)/8]>WALL) ) s=1;/* 左 */
- if ( (ah[no]==3) && (MAP[ay[no]/8][(ax[no]+8)/8]>WALL) ) s=1;/* 右 */
- };
- }
- else
- { /* 乱数による方向変換 */
- while(s==0)
- {
- ah[no]=rnd(3);
- if (ah[no]==wah) continue; /* 現在と反対方向にはしない */
- if ( (ah[no]==0) && (MAP[(ay[no]-1)/8][ax[no]/8]>WALL) ) s=1; /* 上*/
- if ( (ah[no]==1) && (MAP[(ay[no]+8)/8][ax[no]/8]>WALL) ) s=1; /* 下*/
- if ( (ah[no]==2) && (MAP[ay[no]/8][(ax[no]-1)/8]>WALL) ) s=1; /* 左*/
- if ( (ah[no]==3) && (MAP[ay[no]/8][(ax[no]+8)/8]>WALL) ) s=1; /* 右*/
- };
- };
- };
-
- for (i=0;i<8;i++) /* エイリアン同志の衝突判定 */
- {
- if ( (no!=i) && (aj[i]!=0)
- && (abs(ax[no]-ax[i])<6) && (abs(ay[no]-ay[i])<6) )
- {ah[no]=wah; break;}; /* 元の方向の反対方向にする */
- };
-
- if (aj[no]!=2) /* 仮死状態でない */
- {
- switch(ah[no]) /* 移動 */
- {
- case 0: ay[no]--; break; /* 上 */
- case 1: ay[no]++; break; /* 下 */
- case 2: ax[no]--; break; /* 左 */
- case 3: ax[no]++; break; /* 右 */
- };
- };
-
-
- if (no==0)
- { /* ボス */
- if (aj[0]==1) sp_pat(2,12+(ax[0]+ay[0])%2); /* 生存 */
- else sp_pat(2,14); /* 仮死 */
- }
- else
- { /* ザコ */
- if (dot>0) sp_pat(no+2,8+(ax[no]+ay[no])%2); /* ドットあり */
- else sp_pat(no+2,10+(ax[no]+ay[no])%2); /* ドットなし */
- };
-
- sp_move(no+2,ax[no]+X,ay[no]+Y); /* エイリアンの表示 */
- };
-
- };
-
-
- wait()
- {
- int i;
-
- for (i=0;i<300;i++);
-
- };
-
-
- g_put8(a,c)
- /* 8X8dot put高速版(何の制御もなし) */
- int a; /* VRAMアドレス */
- short c[]; /* キャラクタデータ先頭アドレス */
-
- {
- asm(" pushl %ebx");
- asm(" pushl %edx");
- asm(" pushl %esi");
- asm(" pushl %edi"); /* スタック +16 */
-
- asm(" movl 24(%esp),%eax"); /* VRAM アドレス */
- asm(" movl 28(%esp),%ebx"); /* キャラクタデータ アドレス */
-
- asm(" pushl %ds");
-
- asm(" pushl $0x0104"); /* VRAM セレクタ */
- asm(" popl %ds");
-
- asm(" movl $0,%esi"); /* VRAM X方向オフセット */
- asm(" movl $0,%edi"); /* キャラクタデータオフセット */
- asm("lva:movl %ss:(%ebx,%edi,4),%edx");/* キャラクタデータ(4バイト)をedxにロード */
- asm(" movl %edx,(%eax,%esi,4)"); /* edxをVRAMにストア */
- asm(" incl %edi");
- asm(" incl %esi");
- asm(" cmpl $4 , %esi"); /* 1行分のループ */
- asm(" jnz lva");
- asm(" movl $0,%esi"); /* VRAM X方向オフセットのクリア */
- asm(" addl $0x400,%eax"); /* VRAMアドレスの更新 */
- asm(" cmpl $32,%edi"); /* 4X8dot分のループ */
- asm(" jnz lva");
-
- asm(" popl %ds");
-
- asm(" popl %edi");
- asm(" popl %esi");
- asm(" popl %edx");
- asm(" popl %ebx");
-
- };
-
-
- load_chr()
- /* キャラクタパターンデータのバイナリ形式load */
- {
- int i,j;
- unsigned int h,l,end_f;
- int no;
- FILE *fp;
-
- fp=fopen(CHRFILE,"rb"); if (fp==NULL) return 0;
-
- end_f=0;
-
- for (no=0;((no<13)&&(end_f==0));no++)
- {
- for (i=0;i<256;i++)
- {
- h=getc(fp); l=getc(fp); work[no][i]=h*0x100+l;
- if (feof(fp)!=0) {end_f=1; break;};
- };
- };
- fclose(fp);
-
- /* アナログ数字パターンの作成 */
- for (i=0;i<10;i++) {for (j=0;j<256;j++) num[i][j]=work[i+3][j];};
-
- return 1;
-
- };
-
-
- make_chr()
- /* キャラクタパターンデータの8×8分割 */
- {
- int no; /* パターンデータワークの数 */
- int i,j;
-
- for (no=0;no<2;no++)
- {
- for (j=0;j<8;j++)
- {
- for (i=0;i<8;i++)
- {
- chr[no*4+0][j*8+i]=work[no][(j+0)*16+(i+0)];
- chr[no*4+1][j*8+i]=work[no][(j+0)*16+(i+8)];
- chr[no*4+2][j*8+i]=work[no][(j+8)*16+(i+0)];
- chr[no*4+3][j*8+i]=work[no][(j+8)*16+(i+8)];
- };
- };
- };
-
- };
-
-
- load_sprite()
- /* スプライトパターンのバイナリ形式read */
- {
- unsigned int h,l;
- int no,i,end_f;
- short color[16],pat[64];
-
- FILE *fp;
-
- fp=fopen(SPRITE,"rb"); if (fp==NULL) return 0;
-
- /* カラーパレットのread */
- for (i=0;i<16;i++) {h=getc(fp); l=getc(fp); color[i]=h*0x100+l;};
- sp_def_color(0,color);
-
- /* パターンデータのread */
- end_f=0;
- for (no=0;((no<256)&&(end_f==0));no++)
- {
- for (i=0;i<64;i++)
- {
- h=getc(fp); l=getc(fp); pat[i]=h*0x100+l;
- if (feof(fp)!=0) {end_f=1; break;};
- };
- sp_def_pat(no,pat); /* スプライトパターンの設定 */
- };
-
- fclose(fp);
-
- return 1;
-
- };
-
-
- binit()
- /* BGM処理の初期化 */
- {
- int i,j;
-
- for (i=j=0;sdata[i]!=-2;i++)
- {
- if (sdata[i]==-1) {sinit[j]=i+1; j++;}; /* サウンドデータ先頭位置の算出 */
- };
-
- for (i=0;i<6;i++) spoint[i]=0; /* サウンドデータポインタの初期化 */
-
- fm_init();
-
- };
-
-
- bgm()
- /* BGM処理 */
- {
- int ch,oct,tone,vol;
-
- for (ch=0;ch<6;ch++)
- {
- if (sdata[spoint[ch]]>-1) /* 休止状態でない */
- {
- skunt[ch]--;
- if (skunt[ch]<0) /* 変音時期 */
- {
- oct=sdata[spoint[ch]]; spoint[ch]++;
- tone=sdata[spoint[ch]]; spoint[ch]++;
- vol=sdata[spoint[ch]]; spoint[ch]++;
- skunt[ch]=sdata[spoint[ch]]; spoint[ch]++;
- fm_sound(ch,oct,tone,vol,feed[ch]);
- };
- };
- };
-
- };